package com.example.spring.aop.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * spring Aspect 定义切面。
 * 实现对接口日志的查询
 *
 * @author luowj12
 * @since 2021/6/7 8:50
 */

@Component
@Aspect
@Slf4j
public class LogAopAdviseDefine {


    // 定义一个 Pointcut, 使用 切点表达式函数 来描述对哪些 Join point 使用 advice.
    //within()  通过类名指定切点  表示 NeedLogService 下的所有方法
    @Pointcut("within(com.example.spring.aop.service.NeedLogService)")
    public void pointcut() {
    }

    // 定义 advice
    @Before("pointcut()")
    public void logMethodInvokeParam(JoinPoint joinPoint) {
        log.info("---Before method {} invoke, param: {}---", joinPoint.getSignature().toShortString(), joinPoint.getArgs());
    }

    /**
     * 定义 advice
     * @param joinPoint
     * @param retVal
     */
    @AfterReturning(pointcut = "pointcut()", returning = "retVal")
    public void logMethodInvokeResult(JoinPoint joinPoint, Object retVal) {
        log.info("---After method {} invoke, result: {}---", joinPoint.getSignature().toShortString(), joinPoint.getArgs());
    }

    /**
     * 定义 advice
     * @param joinPoint
     * @param exception
     */
    @AfterThrowing(pointcut = "pointcut()", throwing = "exception")
    public void logMethodInvokeException(JoinPoint joinPoint, Exception exception) {
        log.info("---method {} invoke exception: {}---", joinPoint.getSignature().toShortString(), exception.getMessage());
    }

}
